package org.xiaov.lunasql.engine.function;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;

/**
 * <p>
 * GroupConcatFunction
 * </p>
 *
 * @author LunaSQL
 * @since 2024/12/11 21:50
 */
public class GroupConcat2ListAggFunc implements MySqlFunction {

    private final static String METHOD_NAME = "group_concat";
    private final static String TARGET_METHOD_NAME = "listagg";

    @Override
    public boolean accept(SQLMethodInvokeExpr methodInvokeExpr) {
        return methodInvokeExpr.getMethodName().equalsIgnoreCase(METHOD_NAME);
    }

    @Override
    public void transform(SQLMethodInvokeExpr methodInvokeExpr) {
        Object separator = methodInvokeExpr.getAttribute("SEPARATOR");
        SQLExpr sqlExpr = methodInvokeExpr.getArgument(0);
        SQLAggregateExpr sqlAggregateExpr = new SQLAggregateExpr(TARGET_METHOD_NAME);
        sqlAggregateExpr.setOrderBy(new SQLOrderBy(new SQLIdentifierExpr(sqlExpr.toString())));
        sqlAggregateExpr.addArgument(methodInvokeExpr.getArguments().get(0));
        sqlAggregateExpr.addArgument(new SQLIdentifierExpr(separator.toString()));
        sqlAggregateExpr.setWithinGroup(true);

        SQLObject parent = methodInvokeExpr.getParent();
        if (parent instanceof SQLReplaceable replaceable) {
            replaceable.replace(methodInvokeExpr, sqlAggregateExpr);
        }
    }
}
